package basicelement;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;

import istar.IElement;
import istar.ITask;
import istar.agent.IstarJadeAgent;
import istar.behaviour.IstarBehaviour;
import istar.impl.AbstractBasicTask;
import istar.impl.Belief;
import istar.impl.Task;
import jade.core.Agent;
import jade.core.behaviours.Behaviour;
import jade.core.behaviours.OneShotBehaviour;
import jade.lang.acl.ACLMessage;
import log.Log;

import com.rapidminer.RapidMiner;
import com.rapidminer.example.Attribute;
import com.rapidminer.example.Attributes;
import com.rapidminer.example.Example;
import com.rapidminer.example.ExampleReader;
import com.rapidminer.example.ExampleSet;
import com.rapidminer.example.table.AttributeFactory;
import com.rapidminer.example.table.DataRow;
import com.rapidminer.example.table.DataRowFactory;
import com.rapidminer.example.table.DoubleArrayDataRow;
import com.rapidminer.example.table.MemoryExampleTable;
import com.rapidminer.operator.IOContainer;
import com.rapidminer.operator.IOObject;
import com.rapidminer.operator.Model;
import com.rapidminer.operator.ModelApplier;
import com.rapidminer.operator.Operator;
import com.rapidminer.operator.OperatorCreationException;
import com.rapidminer.operator.OperatorException;
import com.rapidminer.operator.io.ExampleSetWriter;
import com.rapidminer.operator.io.ExampleSource;
import com.rapidminer.operator.io.ModelLoader;
import com.rapidminer.tools.Ontology;
import com.rapidminer.tools.OperatorService;
import com.rapidminer.Process;

public class ApplyModel extends AbstractBasicTask{

	private boolean log = true;
	
	
	
	public ApplyModel() {
		super("ApplyModel"); 
	}

	@Override
	public Behaviour getBehaviour() {
		//return new myBehaviour((IstarJadeAgent)this.getOwner(), this);
		return new myBehaviour(this);
	}
	
	private class myBehaviour extends IstarBehaviour{

		//AbstractBasicTask task;
		
		String path_testModel = "";// = "D:\\Documents and Settings\\csid\\workspace\\Fanxaria\\file\\dataset\\VALE5-JAN15-TEST-MAX-MAI-JUN-2009.aml";
		String path_testData = "";// = "D:\\Documents and Settings\\csid\\workspace\\Fanxaria\\file\\dataset\\RESULT-VALE5-JAN15-TEST-MAX-MAI-JUN-2009.dat";
		String path_model_max = "";// = "D:\\Documents and Settings\\csid\\workspace\\Fanxaria\\file\\model\\MODEL-VALE5-JAN15-SVMREG-ABR-OUT2009.mod";
		String path_model_min = "";// = "D:\\Documents and Settings\\csid\\workspace\\Fanxaria\\file\\model\\MODEL-VALE5-JAN15-SVMREG-MIN-ABR-OUT2009.mod";
	
		/*
		public myBehaviour(Agent a, AbstractBasicTask _task){
			super(a);
			task = _task;
			this.setBehaviourName("SeekQuotation");
			try {
				BufferedReader in = new BufferedReader(new FileReader(((IstarJadeAgent)myAgent).configurationPath));
			    String str;
			    while ((str = in.readLine()) != null) {
			        if (str.startsWith("TestModelFile=")){
			        	path_testModel = str.substring(14);
			        }
			        if (str.startsWith("TestDataFile=")){
			        	path_testData = str.substring(13);
			        }
			        if (str.startsWith("ModelMaxFile=")){
			        	path_model_max = str.substring(13);
			        }
			        if (str.startsWith("ModelMinFile=")){
			        	path_model_min = str.substring(13);
			        }

			    }
			    in.close();
			} catch (Exception e) {
				e.printStackTrace();
			}

		}
		*/
		
		public myBehaviour(AbstractBasicTask _task){
			super(_task);
			//task = _task;
		}

		/*
		public myBehaviour(Agent a, AbstractBasicTask _task){
			super(a);
			task = _task;
			this.setBehaviourName("ApplyModel");
		}
		*/

		@Override
		public void myAction() throws Exception {

				BufferedReader in = new BufferedReader(new FileReader(((IstarJadeAgent)myAgent).configurationPath));
			    String str;
			    while ((str = in.readLine()) != null) {
			        if (str.startsWith("TestModelFile=")){
			        	path_testModel = str.substring(14);
			        }
			        if (str.startsWith("TestDataFile=")){
			        	path_testData = str.substring(13);
			        }
			        if (str.startsWith("ModelMaxFile=")){
			        	path_model_max = str.substring(13);
			        }
			        if (str.startsWith("ModelMinFile=")){
			        	path_model_min = str.substring(13);
			        }

			    }
			    in.close();

			
			TendencyIndicator tendency = null;
			
			try {
				OperatorService.createOperator(ExampleSource.class);
			} catch (Exception e) { 
					RapidMiner.init();
					System.out.println(this.getBehaviourName() + " rodou RapidMiner.init()");
			}
			
			try {
				Example example = null;
				IElement previousTask = (IElement)((IstarJadeAgent)myAgent).getKnowledgeElement(getElement().getExecutionNumber(), ((Task)getElement()).getPreviousElement().getId());
				for (int i=0;i<previousTask.getContent().size();i++){
					if (previousTask.getContent().get(i).getClass().equals(Example.class))
						example = (Example)previousTask.getContent().get(i);
				}
				if (example==null)
					throw new Exception("Example not found");
				
				Double lastMax = example.getValue(example.getAttributes().get("Maxima-atual"));
				Double lastMin = example.getValue(example.getAttributes().get("Minima-atual"));
				Double lastPrice = example.getValue(example.getAttributes().get("LAST_PRICE"));
				String id =  example.getValueAsString(example.getAttributes().getId());

				System.out.println("Example: " + example);
				((IstarJadeAgent)myAgent).setKnowledgeObject(getElement().getExecutionNumber(), "Example", example);

				// create table
				ArrayList<Attribute> list = new ArrayList<Attribute>();
				Iterator<Attribute> itAtts = example.getAttributes().iterator();
				while (itAtts.hasNext()){
					list.add(itAtts.next());
				}

				MemoryExampleTable tableMax = new MemoryExampleTable(list);
				MemoryExampleTable tableMin = new MemoryExampleTable(list);
				MemoryExampleTable table = new MemoryExampleTable(list);
				DataRow dataRow = example.getDataRow();
				
				tableMax.addDataRow(dataRow);
				tableMin.addDataRow(dataRow);
				table.addDataRow(dataRow);

				// create example set
				ExampleSet exampleTestMax = tableMax.createExampleSet(example.getAttributes().getLabel());
				ExampleSet exampleTestMin = tableMin.createExampleSet(example.getAttributes().getLabel());
				ExampleSet exampleTendency = table.createExampleSet(example.getAttributes().getLabel());
				
				// create test operators
				IOContainer	containerResultMax = new IOContainer(exampleTestMax);

				// loading the model
				Operator modelLoaderMax = OperatorService.createOperator(ModelLoader.class);
				modelLoaderMax.setParameter("model_file", path_model_max);
				containerResultMax = modelLoaderMax.apply(containerResultMax);
				
				// applying the model
				ModelApplier modelApplierMax = OperatorService.createOperator(ModelApplier.class);
				containerResultMax = modelApplierMax.apply(containerResultMax); 
				
				// print results
				ExampleSet resultSetMax = containerResultMax.get(ExampleSet.class);

				System.out.println("=======================================================");
				/*Iterator<Example> itMax = resultSetMax.iterator();
				Example nextMax = null;
				double predMax = 0;
					
				while (itMax.hasNext()){
					nextMax = itMax.next();
					predMax = nextMax.getPredictedLabel();

					((IstarJadeAgent)myAgent).setKnowledgeObject(task.getExecutionNumber(), "NextMax", predMax);
					//System.out.println(nextMax);
				}
				*/

				Example nextMax = resultSetMax.getExample(0);
				double predMax = nextMax.getPredictedLabel();
				
				IOContainer	containerResultMin = new IOContainer(exampleTestMin);

				Operator modelLoaderMin = OperatorService.createOperator(ModelLoader.class);
				modelLoaderMin.setParameter("model_file", path_model_min);
				containerResultMin = modelLoaderMin.apply(containerResultMin);

				ModelApplier modelApplierMin = OperatorService.createOperator(ModelApplier.class);
				containerResultMin = modelApplierMin.apply(containerResultMin); 
			
				ExampleSet resultSetMin = containerResultMax.get(ExampleSet.class);
				
				/*
				Iterator<Example> itMin = resultSetMin.iterator();
				Example nextMin = null; 
				double predMin = 0;
				while (itMin.hasNext()){
					nextMin = itMin.next();
					predMin = nextMin.getPredictedLabel();
					((IstarJadeAgent)myAgent).setKnowledgeObject(task.getExecutionNumber(), "NextMin", predMin);
					//System.out.println(nextMin);
				}
				*/
				Example nextMin = resultSetMin.getExample(0); 
				double predMin = nextMin.getPredictedLabel();
				
				tendency = new TendencyIndicator(id, lastPrice, lastMin, lastMax, predMin, predMax);
				//System.out.println("Tendency: " + tendency.toString());
				((IstarJadeAgent)myAgent).setKnowledgeObject(getElement().getExecutionNumber(), "Tendency", tendency);

				ACLMessage originalMsg = (ACLMessage)((IstarJadeAgent)myAgent).getKnowledgeElement(getElement().getExecutionNumber(), "Message-Received");
				ACLMessage reply = originalMsg.createReply();
				
				reply.setContentObject(tendency);
				myAgent.send(reply);
			

			} catch (OperatorCreationException e) {
				System.err.println ("Cannot create operator:" + e.getMessage());
				throw e;
			} catch (OperatorException e) {
				System.err . println ("Cannot create model: " + e.getMessage());
				throw e;
			} catch (Exception e) {
				//e.printStackTrace();
				throw e;
			}
			
		}

		@Override
		public int myOnEnd() {
			log("behaviour name="+ getBehaviourName()+" ending ");
			return 1;
		}
		
		

		@Override
		public boolean done() {
			return true;
		}


	};
	

}
